﻿
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Storage;
using MiniErp.Common.DB.MySqlDB;
using MiniErp.Entity.DataStreams;
using MiniErp.Entity.DataStreams.BOs;
using MiniErp.Repository.BaseRepository;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Text;
using System.Threading.Tasks;

namespace MiniErp.Repository.UnitOfWorkCore
{
    public class MysqlUnitOfWork : IMysqlUnitOfWork
    {
        private readonly MysqlContext _mysqlContext;
        private Dictionary<string, object> repositories;
        public MysqlUnitOfWork(MysqlContext mysqlContext)
        {
            _mysqlContext = mysqlContext;
        }


        public BaseRepository<TDBContext, TEntity> CreateRepository<TDBContext, TEntity>()
            where TDBContext : DbContext
            where TEntity : BaseEntity
        {
            if (repositories == null)
            {
                repositories = new Dictionary<string, object>();
            }
            var type = typeof(TEntity).Name;

            if (!repositories.ContainsKey(type))
            {
                var repositoryType = typeof(BaseRepository<,>);

                var test = repositoryType.MakeGenericType(typeof(TDBContext), typeof(TEntity));
                //Activator.CreateInstance创建类的实例（类，构造函数参数）
                //MakeGenericType指定泛型类的泛型类型（有几个泛型就传几个类型
                var repositoryInstance = Activator.CreateInstance(repositoryType.MakeGenericType(typeof(TDBContext), typeof(TEntity)), new MysqlContext[] { _mysqlContext });
                repositories.Add(type, repositoryInstance);
            }
            return (BaseRepository<TDBContext, TEntity>)repositories[type];
        }

        public int Save()
        {
            return _mysqlContext.SaveChanges();
        }

        public async Task<int> SaveAsync()
        {
            return await _mysqlContext.SaveChangesAsync();
        }

        public async Task<bool> DataRollback(string message, int nums = 1)
        {
            for (var i = 0; 0 < nums; i++)
            {
                await _mysqlContext.Database.BeginTransactionAsync();
            }
            throw new ExceptionBO(message);//出现回滚则说明已经出现异常情况
        }

        public void EndTracking<TEntity>() where TEntity : BaseEntity
        {
            //获取指定实体的跟踪状态
            var currentEntry = _mysqlContext.ChangeTracker.Entries().FirstOrDefault(item => item.Entity is TEntity);
            if (currentEntry != null)
            {
                //移除指定实体的跟踪状态
                currentEntry.State = EntityState.Detached;
            }
        }
    }
}
